package com.bupt.websocket.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bupt.websocket.config.ValProperties;
import com.jyt.message.Message;
import com.jyt.message.MessageConfig;

import com.jyt.util.MySerializable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import com.bupt.websocket.utils.ClientWeb;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket/{user}")
public class WebPush {
    //静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    @Value("${backhend_server_ip}")
    private String BACKHEND_SERVER_IP;

    private static int onlineCount = 0;
    private Jedis jedis;

    public static ConcurrentHashMap<String,ClientWeb> clients2=new ConcurrentHashMap<String, ClientWeb>();
    private static ConcurrentHashMap<String,Session> clients=new ConcurrentHashMap<String, Session>();
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    //private static CopyOnWriteArraySet<WebPush> webSocketSet = new CopyOnWriteArraySet<WebPush>();

    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("user")String user, Session session){
        this.session = session;
        ClientWeb clientWeb = new ClientWeb(BACKHEND_SERVER_IP, MessageConfig.server_name, user,this );
        int register = clientWeb.register(user);
        clientWeb.work();
        synchronized (this) {
            clients2.put(user, clientWeb);
            clients.put(user, session);
        }
        addOnlineCount();           //在线数加1
        System.out.println("one connection established, now connections amount:" + getOnlineCount());
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("user")String user){

            ClientWeb clientWeb = clients2.get(user);
            if(clientWeb!=null) {
                clientWeb.unregister(user);
                clientWeb.shutdown();
            }
            clients2.remove(user);
         ///   clients.remove(user);
            subOnlineCount();           //在线数减1

        System.out.println("one connectino closed, now connections amount:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(@PathParam("user") String user, String message, Session session) {
        JSONObject obj=JSON.parseObject(message);
        System.out.println("来自客户端的消息:" + JSON.parse(message));

        //发送至群的消息groupMsg {'gid':'xxx', 'uid':'xxx' ,'content':'xxx'}
        //发送至好友的msg {'from':'xxx', 'to':'xxx', 'content':'xxx'}
        String gid = obj.getString("gid");
        String from = obj.getString("from");

        if(from!=null){
            //若是单聊则发送至对方client
            String to=obj.getString("to");
            Message message1 = new Message();
            message1.setContent(MySerializable.object_bytes(message));
            message1.setFrom(from);
            message1.setTo(to);
            message1.setType("msg");

            ClientWeb clientWeb = clients2.get(user);
            if(null!=clientWeb)clientWeb.send(message1);
        }else if(gid!=null){
            //若是群聊则发送至群服务器，由群服务器负责群发；
            String uid=obj.getString("uid");
            Message message1 = new Message();

            message1.setContent(MySerializable.object_bytes(message));
            message1.setFrom(uid);
            message1.setTo("sys_groups");
            message1.setType("groupMsg");

            ClientWeb clientWeb = clients2.get(user);
            if(null!=clientWeb)clientWeb.send(message1);

        }

    }

    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        System.out.println("发生错误");
        error.printStackTrace();
    }

    /**
     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String user,String message) throws IOException{
        clients.get(user).getBasicRemote().sendText(message);
    }
    public void sendToAll(String message){
        for (Map.Entry<String, Session> item:clients.entrySet()){
            try {
                item.getValue().getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebPush.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebPush.onlineCount--;
    }


    //------------------------------------------
     /*class ClientWeb extends MessageServerTcpClient {


        public ClientWeb(String server_ip, String server_name, String entityName) {
            super(server_ip, server_name,entityName);
            addListener("msg",new WebResponseListener());
            addListener("groupMsg",new WebResponseListener());
        }



        public class WebResponseListener implements MessageListener
        {
            public void messagePerformed(Message message)
            {
                String field = "**************\n%1 from %2 \n%3\n**************";
                String type = message.getType();
                String time_str = MyDate.f2(message.getCreated());
                String to = message.getTo();
                String from = message.getFrom();


                String content = (String) MySerializable.bytes_object(message.getContent());
                String[] ss = new String[]{time_str,from,content};
                String result = ArgumentString.replace(field,ss);


                try {
                    sendMessage(to, content);
                    System.out.println("用户："+ to + "\t收到消息：\t"+ content);
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

        }


    }*/

}
